﻿using AlibabaCloud.SDK.Dysmsapi20170525;
using AlibabaCloud.SDK.Dysmsapi20170525.Models;
using CSRedis;
using furion.blog.Application.Contracts;
using furion.blog.Application.KafkaMQ.Producers;
using furion.blog.Domain.Shared.Dto.Sms;
using furion.blog.Utils;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tea;

namespace furion.blog.Application
{
    public class SmsService : ISmsService, ISingleton
    {
        private readonly CSRedisClient[] _csredis;
        private readonly AliSmsSendRecordProducer _aliSmsSendRecordProducer;
        public SmsService(CSRedisClient[] csredis,AliSmsSendRecordProducer aliSmsSendRecordProducer) {
            this._csredis = csredis;
            this._aliSmsSendRecordProducer = aliSmsSendRecordProducer;
        }

        private Client CreateClient(string accessKey, string accessKeySecret)
        {
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
            {
                // 您的 AccessKey ID
                AccessKeyId = accessKey,
                // 您的 AccessKey Secret
                AccessKeySecret = accessKeySecret,
            };
            // 访问的域名
            config.Endpoint = "dysmsapi.aliyuncs.com";
            return new Client(config);
        }

        /// <summary>
        /// 发送短信验证码
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> SendCaptcha(SmsSendDto dto) {
            SendSmsResponse ret = await Send(dto);
            if (ret.Body.Code.ToUpper() == "OK" && ret.Body.Message == "OK") {
                //发送成功,保存到redis
                var ok = await this._csredis[13].SetAsync(dto.Phone,dto.TempParams["code"],60*10);
                if (!ok) {
                    throw Oops.Oh("redis保存失败");
                }
                //通过MQ，把请求信息写入mongo
                await this._aliSmsSendRecordProducer.CreateAsync(new
                {
                    Request = dto,
                    Response = ret,
                    CreatedTime = DateTime.Now,
                }) ;
            }
            return false;
        }

        /// <summary>
        /// 验证码发送
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        private async Task<SendSmsResponse> Send(SmsSendDto dto)
        {
            var ret = await Task.Run<SendSmsResponse>(() =>
            {
                string templateParam = string.Empty;
                
                AlibabaCloud.SDK.Dysmsapi20170525.Client client = CreateClient(dto.AccessKey, dto.AccessSecret);
                AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest sendSmsRequest = new AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest
                {
                    PhoneNumbers = dto.Phone,
                    SignName = dto.TempName,
                    TemplateCode = dto.TempCode,
                    TemplateParam = templateParam == null?null:JsonConvert.SerializeObject(dto.TempParams),
                };
                AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
                try
                {
                    // 复制代码运行请自行打印 API 的返回值
                    SendSmsResponse response = client.SendSmsWithOptions(sendSmsRequest, runtime);
                    return response;
                }
                catch (TeaException error)
                {
                    // 如有需要，请打印 error
                    AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
                    return null;
                }
                catch (Exception _error)
                {
                    TeaException error = new TeaException(new Dictionary<string, object>
                {
                    { "message", _error.Message }
                });
                    // 如有需要，请打印 error
                    AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
                    return null;
                }
            });
            return ret;
        }

    }
}
